package mapEditor.interactor;

import debug.*;

import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;

import mapEditor.map.MapCanvas;
import mapEditor.utils.MapLocation;

/**
 * This class represents a pan interactor.
 * To use it, just redefine the {@link
 * InteractorAdapter#startInteraction(InputEvent)} method.
 *
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id: AbstractPanInteractor.java 478176 2006-11-22 14:50:50Z dvholten $
 */
public class PanInteractor extends MapInteractorAdapter
{ public String getMouseModeMnemonic() { return("Pan"); }
  public static final Cursor PAN_CURSOR = new Cursor(Cursor.MOVE_CURSOR);
  public static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR);
  private Cursor previousCursor; // To save the previous cursor.

  private boolean panning; // Whether the interactor has !panning.

  private int xStart; // The mouse x start position.
  private int yStart; // The mouse y start position.
  private int xCurrent; // The mouse x current position.
  private int yCurrent; // The mouse y current position.

  // ******************************************************************
  // *** CONSTRUCTOR: PanInteractor
  // ******************************************************************
  public PanInteractor(MapCanvas mapCanvas)
  { super(mapCanvas,PAN); }

    /**
     * Tells whether the interactor has !panning.
     */
//    public boolean endInteraction() { return(!panning); }
    
    // ******************************************************************
    // *** METHOD: paintMouseEffect
    // ******************************************************************
    public void paintMouseEffect(Graphics2D g) { }

    // ******************************************************************
    // *** METHOD: mouseDragged
    // ******************************************************************
    // Invoked when a mouse button is pressed and then dragged.
    protected void mouseDragged()
    { xCurrent =(int)mouseCurrent.getX();
      yCurrent =(int)mouseCurrent.getY();
      AffineTransform at=AffineTransform.getTranslateInstance(xCurrent-xStart,yCurrent-yStart);
      mapCanvas.setPaintingTransform(at);
   }

    // ******************************************************************
    // *** METHOD: mouseMoved
    // ******************************************************************
    // Invoked when the mouse has been moved (with no buttons down).
    protected void mouseMoved() {}

    // ******************************************************************
    // *** METHOD: mousePressed
    // ******************************************************************
    // Invoked when a mouse button has been pressed.
    protected void mouseLeftPressed(MapLocation p)
    { if(!panning)
      { panning=true;
        xStart=(int)p.getX();
        yStart=(int)p.getY();
        previousCursor=mapCanvas.getCursor();
        mapCanvas.setCursor(PAN_CURSOR);  
      } else mouseExited(null);
    }
    protected void mouseRightPressed(MapLocation p) {}


    // ******************************************************************
    // *** METHOD: mouseReleased
    // ******************************************************************
    // Invoked when a mouse button has been released.
    protected void mouseLeftReleased(MapLocation p)
    { if(panning)
      { panning=false;
        xCurrent=(int)p.getX();
        yCurrent=(int)p.getY();
        AffineTransform at=AffineTransform.getTranslateInstance(xCurrent-xStart,yCurrent-yStart);
        AffineTransform rt=(AffineTransform)mapCanvas.getRenderingTransform().clone();
        rt.preConcatenate(at);
        mapCanvas.setRenderingTransform(rt);
        if(mapCanvas.getCursor()==PAN_CURSOR) { mapCanvas.setCursor(previousCursor); }
      }
    }
    protected void mouseRightReleased(MapLocation p) {}

    /**
     * Invoked when the mouse exits a component.
     */
    public void mouseEntered(MouseEvent e)
    { //panning=false;
      Debug.TRACE("MOUSE ENTERED: MouseEvent="+e);
//      mapCanvas.setPaintingTransform(null);
      previousCursor=mapCanvas.getCursor();
      mapCanvas.setCursor(HAND_CURSOR);
    }

    /**
     * Invoked when the mouse exits a component.
     */
    public void mouseExited(MouseEvent e)
    { panning=false;
      mapCanvas.setPaintingTransform(null);
      if(mapCanvas.getCursor()==PAN_CURSOR) { mapCanvas.setCursor(previousCursor); }
    }

}
